<script setup>
import {downLoadbyPiece } from '../lib/api1';
import { reactive } from '@vue/reactivity';
//下载逻辑
const downloadObj = reactive({
  fileName: '',
  downloading: false,
  range: 0,
  fileBlob: [],
  percentage: 0,
  count:1,
})


const download = async () => {
  downloadObj.fileBlob = []
  downloadObj.downloading = true
  downloadObj.range = 0 //文件总大小
  downloadObj.percentage = 0 //下载进度
  const identifier='1499170fe7c15f5589f03c3d72201f5a'

  const chunkSize = 5 * 1024 * 1024

  //第一次调接口获取到响应头的content-range，文件总大小，用于计算下载切割
  const config = {
    headers: {
      Range: `bytes=0-${chunkSize}`,
    },
    responseType:'blob',
  }

  const data = await downLoadbyPiece(identifier, config)

  console.log(data.headers);
  //获取文件总大小
  const arr = data.headers['content-range'].split('/')
  downloadObj.range = Number(arr[1])
  //存储每片文件流
  //const blob = new Blob([data.data], {type: data.headers['content-type']});
  downloadObj.fileBlob[0]=data.data;
  //获取文件名称
  let fileName = ''
  let cd = data.headers['content-disposition']
  if (cd) {
    let index = cd.lastIndexOf('=')
    fileName = decodeURI(cd.substring(index + 1, cd.length))
  }

  //拿到文件总大小downloadObj.range，计算分为多少都段下载
   //获取分段下载的数组
   let chunkList = []
  function chunkPush(page = 1) {
    chunkList.push((page - 1) * chunkSize)
    if (page * chunkSize < downloadObj.range) {
      chunkPush(page + 1)
    }
  }
  chunkPush()

  //加上文件大小在最后一位
  chunkList.push(downloadObj.range)
  console.log(chunkList, 'chunkList')
  //分段组合传参格式处理 0-1024 1024-2048
  let uploadRange = []
  downloadObj.count=chunkList.length - 1
  chunkList.forEach((item, i) => {
    if (i == chunkList.length - 1) return

    uploadRange.push(`${chunkList[i]}-${chunkList[i + 1]}`)
  })
  console.log(uploadRange, 'uploadRang')

  sendRequest(identifier,uploadRange, 5, () => {
        //合并
        const blob = new Blob(downloadObj.fileBlob, {
            type: downloadObj.fileBlob[0].type,
        })
        downloadObj.downloading = false
        //下载
        const link = document.createElement('a')
        link.href = window.URL.createObjectURL(blob)
        link.download = fileName
        link.click()
        window.URL.revokeObjectURL(link.href)
  });

}

function sendRequest(identifier,uploadRange, max, callbackFunc) {
  const REQUEST_MAX = max;
  const TOTAL_REQUESTS_NUM = uploadRange.length-1;
  const blockQueue = []; // 等待排队的那个队列
  let currentReqNumber = 0; // 现在请求的数量是
  let numberOfRequestsDone = 0; // 已经请求完毕的数量是
  async function init() {
    for (let i = 0; i < uploadRange.length; i++) {
            //第一次调接口已经传过了第一组，从第二位开始
        if (i > 0) {
            request(identifier,i, uploadRange[i]);
        }
    }
  }

  async function request(identifier,index, reqUrl) {
    // 这个index传过来就是为了对应好哪个请求，
    // 放在对应的results数组对应位置上的，保持顺序
    if (currentReqNumber >= REQUEST_MAX) {
      await new Promise((resolve) => blockQueue.push(resolve)); // 阻塞队列增加一个 Pending 状态的 Promise，
      // 进里面排队去吧，不放你出来，不resolve你，你就别想进行下面的请求
    }
    reqHandler(identifier,index, reqUrl); // {4}
  }

  async function reqHandler(identifier,index, reqUrl) {
    currentReqNumber++; // {5}
    try {
        const config = {
        headers: {
          Range: `bytes=${reqUrl}`,
        },
        responseType:'blob'
      }
      const result = await downLoadbyPiece(identifier, config)
      downloadObj.fileBlob[index] = result.data;
    } catch (err) {
      console.log(err)
    } finally {
      currentReqNumber--;
      numberOfRequestsDone++;
      if (blockQueue.length) {
        // 每完成一个就从阻塞队列里剔除一个
        blockQueue[0](); // 将最先进入阻塞队列的 Promise 从 Pending 变为 Fulfilled，
        // 也就是执行resolve函数了，后面不就能继续进行了嘛
        blockQueue.shift();
      }
      downloadObj.percentage = Math.floor(((numberOfRequestsDone) / TOTAL_REQUESTS_NUM) * 100)
      if (numberOfRequestsDone === TOTAL_REQUESTS_NUM) {
        callbackFunc();
      }
    }
  }

  init();
}



</script>
<template>

    <g-button style="margin-top: 20px" type="primary" :loading="downloadObj.downloading" @click="download"> {{ downloadObj.downloading ? '下载中...' : '下载文件' }}</g-button>
    <span> 下载进度（{{ downloadObj.percentage }}%）</span>

</template>
